/*
* Copyright (c) 2014 the original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.werval.modules.xml.internal;
import java.io.File;
import java.net.URL;
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import javax.xml.validation.ValidatorHandler;
import io.werval.modules.xml.UncheckedXMLException;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import static io.werval.modules.xml.internal.Internal.ACCESS_EXTERNAL_ALL;
import static io.werval.modules.xml.internal.Internal.ACCESS_EXTERNAL_NONE;
import static io.werval.modules.xml.internal.Internal.LOG;
/**
* RelaxNG SchemaFactory implementation for XMLPlugin.
* <p>
* Factory that creates {@link Schema} objects.
* Entry-point to the validation API.
*
* @see SchemaFactory
*/
public final class SchemaFactoryRelaxNG
extends SchemaFactory
{
// Jing for RelaxNG
private final SchemaFactory delegate = new com.thaiopensource.relaxng.jaxp.XMLSyntaxSchemaFactory();
public SchemaFactoryRelaxNG()
throws SAXException
{
super();
delegate.setFeature( XMLConstants.FEATURE_SECURE_PROCESSING, true );
try
{
delegate.setProperty(
XMLConstants.ACCESS_EXTERNAL_DTD,
Internal.EXTERNAL_ENTITIES.get() ? ACCESS_EXTERNAL_ALL : ACCESS_EXTERNAL_NONE
);
}
catch( SAXException ex )
{
LOG.trace( "JAXP<1.5 - {} on {}", ex.getMessage(), delegate );
}
try
{
delegate.setProperty(
XMLConstants.ACCESS_EXTERNAL_SCHEMA,
Internal.EXTERNAL_ENTITIES.get() ? ACCESS_EXTERNAL_ALL : ACCESS_EXTERNAL_NONE
);
}
catch( SAXException ex )
{
LOG.trace( "JAXP<1.5 - {} on {}", ex.getMessage(), delegate );
}
delegate.setResourceResolver( Internal.RESOLVER.get() );
delegate.setErrorHandler( Errors.INSTANCE );
}
@Override
public boolean isSchemaLanguageSupported( String schemaLanguage )
{
return delegate.isSchemaLanguageSupported( schemaLanguage );
}
@Override
public boolean getFeature( String name )
throws SAXNotRecognizedException, SAXNotSupportedException
{
return delegate.getFeature( name );
}
@Override
public void setFeature( String name, boolean value )
throws SAXNotRecognizedException, SAXNotSupportedException
{
delegate.setFeature( name, value );
}
@Override
public void setProperty( String name, Object object )
throws SAXNotRecognizedException, SAXNotSupportedException
{
delegate.setProperty( name, object );
}
@Override
public Object getProperty( String name )
throws SAXNotRecognizedException, SAXNotSupportedException
{
return delegate.getProperty( name );
}
@Override
public void setErrorHandler( ErrorHandler errorHandler )
{
delegate.setErrorHandler( errorHandler );
}
@Override
public ErrorHandler getErrorHandler()
{
return delegate.getErrorHandler();
}
@Override
public void setResourceResolver( LSResourceResolver resourceResolver )
{
delegate.setResourceResolver( resourceResolver );
}
@Override
public LSResourceResolver getResourceResolver()
{
return delegate.getResourceResolver();
}
@Override
public Schema newSchema( Source schema )
throws SAXException
{
return new XSDSchemaImpl( delegate.newSchema( schema ) );
}
@Override
public Schema newSchema( File schema )
throws SAXException
{
return new XSDSchemaImpl( delegate.newSchema( schema ) );
}
@Override
public Schema newSchema( URL schema )
throws SAXException
{
return new XSDSchemaImpl( delegate.newSchema( schema ) );
}
@Override
public Schema newSchema( Source[] schemas )
throws SAXException
{
return new XSDSchemaImpl( delegate.newSchema( schemas ) );
}
@Override
public Schema newSchema()
throws SAXException
{
return new XSDSchemaImpl( delegate.newSchema() );
}
private static final class XSDSchemaImpl
extends Schema
{
private final Schema schema;
private XSDSchemaImpl( Schema schema )
{
this.schema = schema;
}
@Override
public Validator newValidator()
{
Validator validator = schema.newValidator();
try
{
validator.setFeature( XMLConstants.FEATURE_SECURE_PROCESSING, true );
}
catch( SAXException ex )
{
throw new UncheckedXMLException( ex );
}
try
{
validator.setProperty(
XMLConstants.ACCESS_EXTERNAL_DTD,
Internal.EXTERNAL_ENTITIES.get() ? ACCESS_EXTERNAL_ALL : ACCESS_EXTERNAL_NONE
);
}
catch( SAXException ex )
{
LOG.trace( "JAXP<1.5 - {} on {}", ex.getMessage(), validator );
}
try
{
validator.setProperty(
XMLConstants.ACCESS_EXTERNAL_SCHEMA,
Internal.EXTERNAL_ENTITIES.get() ? ACCESS_EXTERNAL_ALL : ACCESS_EXTERNAL_NONE
);
}
catch( SAXException ex )
{
LOG.trace( "JAXP<1.5 - {} on {}", ex.getMessage(), validator );
}
validator.setResourceResolver( Internal.RESOLVER.get() );
validator.setErrorHandler( Errors.INSTANCE );
return validator;
}
@Override
public ValidatorHandler newValidatorHandler()
{
ValidatorHandler handler = schema.newValidatorHandler();
try
{
handler.setFeature( XMLConstants.FEATURE_SECURE_PROCESSING, true );
}
catch( SAXException ex )
{
throw new UncheckedXMLException( ex );
}
try
{
handler.setProperty(
XMLConstants.ACCESS_EXTERNAL_DTD,
Internal.EXTERNAL_ENTITIES.get() ? ACCESS_EXTERNAL_ALL : ACCESS_EXTERNAL_NONE
);
}
catch( SAXException ex )
{
LOG.trace( "JAXP<1.5 - {} on {}", ex.getMessage(), handler );
}
try
{
handler.setProperty(
XMLConstants.ACCESS_EXTERNAL_SCHEMA,
Internal.EXTERNAL_ENTITIES.get() ? ACCESS_EXTERNAL_ALL : ACCESS_EXTERNAL_NONE
);
}
catch( SAXException ex )
{
LOG.trace( "JAXP<1.5 - {} on {}", ex.getMessage(), handler );
}
handler.setResourceResolver( Internal.RESOLVER.get() );
handler.setErrorHandler( Errors.INSTANCE );
return handler;
}
}
}